#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "global.h"
#include "constantes.h"
#include "listas.h"


int	AgregarAColaGlobal(struct ListaIDdescriptors ** pnodo, struct ListaIDdescriptors ** ListaDeIDPedidos, struct ListaIDdescriptors ** ListaDeIDPedidos_Ult )
{

	if((*ListaDeIDPedidos) == NULL)
	{
		(*pnodo)->Ant = NULL;
		(*pnodo)->Sgt = NULL;
		(*ListaDeIDPedidos) = (*pnodo);
	}	
	else
	{
		(*pnodo)->Ant = *ListaDeIDPedidos_Ult;	
		(*pnodo)->Sgt = NULL;
		(*ListaDeIDPedidos_Ult)->Sgt = (*pnodo);
	}
	
	*ListaDeIDPedidos_Ult=*pnodo;

}



int agregarAListaDeDiscos(struct DiscoConocido ** pnodo)			/*Agrega el nodo a la lista ListaDiscos (enlazar) */
{

	if((ListaDiscos) == NULL)
	{
		(*pnodo)->Ant = NULL;
		(*pnodo)->Sgt = NULL;
		ListaDiscos = (*pnodo);
	}	
	else
	{
		(*pnodo)->Ant = ListaDiscos_Ult;	
		(*pnodo)->Sgt = NULL;
		ListaDiscos_Ult->Sgt = (*pnodo);
	}
	
	ListaDiscos_Ult=*pnodo;



}



int agregarAListaDeClientes(cliente ** pnodo)			/*Agrega el nodo a la lista ListaDiscos (enlazar) */
{


	if((ListaClientes) == NULL)
	{
		(*pnodo)->Ant = NULL;
		(*pnodo)->Sgt = NULL;
		ListaClientes = (*pnodo);
	}	
	else
	{
		(*pnodo)->Ant = ListaClientes_Ult;	
		(*pnodo)->Sgt = NULL;
		ListaClientes_Ult->Sgt = (*pnodo);
	}
	
	ListaClientes_Ult=*pnodo;

}


void AgregarAColaControl(t_control ** pnodo){

	
	
	if((colaControl) == NULL)
	{
		(*pnodo)->Ant = NULL;
		(*pnodo)->Sgt = NULL;
		colaControl = (*pnodo);
	}	
	else
	{
		(*pnodo)->Ant = colaControl_Ult;	
		(*pnodo)->Sgt = NULL;
		colaControl_Ult->Sgt = (*pnodo);
	}
	
	colaControl_Ult=*pnodo;
	
}


int SacarDeColaControl2(t_control ** nodo, t_control ** ListaDeIDPedidos, t_control ** ListaDeIDPedidos_Ult)
{
	
	if(  ((*nodo)->Ant == NULL) && ((*nodo)->Sgt == NULL)  )
	{
		(*ListaDeIDPedidos_Ult) = NULL;
		(*ListaDeIDPedidos) = NULL;
	}
	else if(  ((*nodo)->Ant == NULL) && ((*nodo)->Sgt != NULL)  )
	{
		(*ListaDeIDPedidos) = (*nodo)->Sgt;
		(*ListaDeIDPedidos)->Ant = NULL;			
	}
	else if(  ((*nodo)->Ant != NULL) && ((*nodo)->Sgt == NULL)  )
	{
		(*ListaDeIDPedidos_Ult) = (*nodo)->Ant;
		(*ListaDeIDPedidos_Ult)->Sgt = NULL;					
	}
	else if(  ((*nodo)->Ant != NULL) && ((*nodo)->Sgt != NULL)  )
	{
		(*nodo)->Ant->Sgt=(*nodo)->Sgt;
		(*nodo)->Sgt->Ant=(*nodo)->Ant;
	}

	return 0;

}

t_control * BuscarDescriptorEnColaControl(t_control * ListaDeIDPedidos, char * sDescriptorIDABuscar)		//busca un la lista de descriptores del disco por opciones: (en este el sDescriptorID_delDA que sea igual sDescriptorID, y lo saca de la lista)
{
	t_control * pNodo;
	pNodo = ListaDeIDPedidos;

	while(pNodo != NULL)
	{
		if(!strcmp(pNodo->sDescriptorID_delPedido , sDescriptorIDABuscar))
			return pNodo;
		pNodo = pNodo->Sgt;
	}
	
	
	printf("NO SE ENCONTRO Cola Control\n");
	return NULL;

}



pedido * SacarPrimerNodoDeRespuestaSinc(pedido ** ListaDeIDPedidos,pedido ** ListaDeIDPedidos_Ult)		//busca un la lista de descriptores del disco por opciones: (en este el sDescriptorID_delDA que sea igual sDescriptorID, y lo saca de la lista)
{
	pedido *pNodo = *ListaDeIDPedidos;

	while(pNodo != NULL)
	{
		if(((pNodo->operacion==3) && (pNodo->estado==1))|| ((pNodo->operacion==4)&&(pNodo->estado==1)))
			break;
		pNodo = pNodo->Sgt;
	}
	if(pNodo!=NULL)
		SacarNodoDescriptoresDeLista2(&pNodo,&(*ListaDeIDPedidos),&(*ListaDeIDPedidos_Ult));
	
	return pNodo;
}

struct ListaIDdescriptors * SacarNodoDescriptoresDeLista(struct ListaIDdescriptors ** ListaDeIDPedidos, struct ListaIDdescriptors ** ListaDeIDPedidos_Ult)
{
	struct ListaIDdescriptors * temp;
	
	temp=*ListaDeIDPedidos;
	*ListaDeIDPedidos=(*ListaDeIDPedidos)->Sgt;
	if(*ListaDeIDPedidos == NULL){
      *ListaDeIDPedidos_Ult=NULL;
	}
	return temp;
	
}



struct DiscoConocido * BuscarDiscoPorNombre(char * sNombreDiscoABuscar)		/* busca disco por sNombre, y devuelve el nodo, NULL si no lo encuentra*/
{
	struct DiscoConocido * pNodo;

	pNodo = ListaDiscos;

	while(pNodo != NULL)
	{
		if(!(strcmp(pNodo->sNombre , sNombreDiscoABuscar)))
			return pNodo;
		pNodo = pNodo->Sgt;
	}

	return NULL;

}



struct DiscoConocido * BuscarDiscoPorSocketParaDA(int iSocket)		
{

struct DiscoConocido * pNodo;
	
	
	pNodo = ListaDiscos;

	while(pNodo != NULL)
		{
		if(pNodo->iSocketHDAParaDA  == iSocket)
			return pNodo;
		pNodo = pNodo->Sgt;
		}

return NULL;

}






struct DiscoConocido * BuscarDiscoListo()	
{

struct DiscoConocido * pNodo;
	
	
	pNodo = ListaDiscos;

	while(pNodo != NULL)
		{
		if(pNodo->Estado == LISTO)
			return pNodo;
		pNodo = pNodo->Sgt;
		}

return NULL;

}




int	SacarDeLista_DA(struct DiscoConocido ** nodo)  /*solo desenalzar el nodo de la lista ListaDA , sin liberar*/
{



if(  ((*nodo)->Ant == NULL) && ((*nodo)->Sgt == NULL)  )
	{
	ListaDiscos_Ult = NULL;
	ListaDiscos = NULL;

	}
else if(  ((*nodo)->Ant == NULL) && ((*nodo)->Sgt != NULL)  )
	{
	ListaDiscos = (*nodo)->Sgt;
	ListaDiscos->Ant = NULL;
	}

else if(  ((*nodo)->Ant != NULL) && ((*nodo)->Sgt == NULL)  )
	{

	ListaDiscos_Ult = (*nodo)->Ant;
	ListaDiscos_Ult->Sgt = NULL;

	}
else if(  ((*nodo)->Ant != NULL) && ((*nodo)->Sgt != NULL)  )
	{
	(*nodo)->Ant->Sgt=(*nodo)->Sgt;
	(*nodo)->Sgt->Ant=(*nodo)->Ant;

	}



return 0;

}



int	SacarDeLista_Clientes(cliente ** nodo)  /*solo desenalzar el nodo de la lista ListaDA , sin liberar*/
{

if(  ((*nodo)->Ant == NULL) && ((*nodo)->Sgt == NULL)  )
	{
	ListaClientes_Ult = NULL;
	ListaClientes = NULL;

	}
else if(  ((*nodo)->Ant == NULL) && ((*nodo)->Sgt != NULL)  )
	{
	ListaClientes = (*nodo)->Sgt;
	ListaClientes->Ant = NULL;
	}

else if(  ((*nodo)->Ant != NULL) && ((*nodo)->Sgt == NULL)  )
	{

	ListaClientes_Ult = (*nodo)->Ant;
	ListaClientes_Ult->Sgt = NULL;

	}
else if(  ((*nodo)->Ant != NULL) && ((*nodo)->Sgt != NULL)  )
	{
	(*nodo)->Ant->Sgt=(*nodo)->Sgt;
	(*nodo)->Sgt->Ant=(*nodo)->Ant;

	}



return 0;


}





int estaVacia(struct ListaIDdescriptors * ListaDeIDPedidos){

   return ListaDeIDPedidos==NULL;

}




int estaVacia2(disco * listaDiscos){

   return listaDiscos==NULL;

}


int longitud(struct ListaIDdescriptors *  ptrActual) {
	
	int n=0;
	
	while (ptrActual != NULL) {  
      ++n;
	   ptrActual = ptrActual->Sgt;
	}
	return n;

}


int longitud2(struct DiscoConocido *  ptrActual) {
	
	int n=0;
	
	while (ptrActual != NULL) {  
      ++n;
	   ptrActual = ptrActual->Sgt;
	}
	return n;

}


struct ListaIDdescriptors * BuscarDescriptorEnListaDeDisco(struct ListaIDdescriptors * ListaDeIDPedidos, char * sDescriptorIDABuscar)		//busca un la lista de descriptores del disco por opciones: (en este el sDescriptorID_delDA que sea igual sDescriptorID, y lo saca de la lista)

{
	struct ListaIDdescriptors * pNodo;
	pNodo = ListaDeIDPedidos;

	while(pNodo != NULL)
	{
		if(!strcmp(pNodo->sDescriptorID_delPedido , sDescriptorIDABuscar)){
			return pNodo;	
		}	
		pNodo = pNodo->Sgt;
	}
	printf("NO SE ENCONTRO Descriptor\n");
	return NULL;

}

pedido * BuscarDescriptorEnListaDeDisco_Sinc(pedido* ListaDeIDPedidos,int sector)
{
	pedido *pNodo = ListaDeIDPedidos;

	while(pNodo != NULL)
	{
		if(pNodo->estado==1 && !(strcmp(pNodo->sSocketPorElCualResponder,"-1")) && pNodo->numeroSector == sector) //Estado == 1; ENVIADO
			break;
		pNodo = pNodo->Sgt;
	}
	
	return pNodo;
}

pedido * Buscar(pedido* ListaDeIDPedidos,pedido* ListaDeIDPedidos_Ult){


	pedido *pNodo = ListaDeIDPedidos;

	while(pNodo != NULL)
	{
		if(((pNodo->operacion==3) && (pNodo->estado==-1))|| ((pNodo->operacion==4)&&(pNodo->estado==-1)))
			break;
		pNodo = pNodo->Sgt;
	}
	
	return pNodo;
}

	
int SacarNodoDescriptoresDeLista2(struct ListaIDdescriptors ** nodo, struct ListaIDdescriptors ** ListaDeIDPedidos, struct ListaIDdescriptors ** ListaDeIDPedidos_Ult)
{
	
	if(  ((*nodo)->Ant == NULL) && ((*nodo)->Sgt == NULL)  )
	{
		(*ListaDeIDPedidos_Ult) = NULL;
		(*ListaDeIDPedidos) = NULL;
	}
	else if(  ((*nodo)->Ant == NULL) && ((*nodo)->Sgt != NULL)  )
	{
		(*ListaDeIDPedidos) = (*nodo)->Sgt;
		(*ListaDeIDPedidos)->Ant = NULL;			
	}
	else if(  ((*nodo)->Ant != NULL) && ((*nodo)->Sgt == NULL)  )
	{
		(*ListaDeIDPedidos_Ult) = (*nodo)->Ant;
		(*ListaDeIDPedidos_Ult)->Sgt = NULL;					
	}
	else if(  ((*nodo)->Ant != NULL) && ((*nodo)->Sgt != NULL)  )
	{
		(*nodo)->Ant->Sgt=(*nodo)->Sgt;
		(*nodo)->Sgt->Ant=(*nodo)->Ant;
	}

	return 0;

}


int	AgregarAColaDePedidosADisco(struct ListaIDdescriptors ** pnodo, struct ListaIDdescriptors ** ListaDeIDPedidos, struct ListaIDdescriptors ** ListaDeIDPedidos_Ult )
{
	struct ListaIDdescriptors *anterior;
	struct ListaIDdescriptors *aux;
	
	if((*ListaDeIDPedidos) == NULL)
	{
		(*pnodo)->Ant = NULL;
		(*pnodo)->Sgt = NULL;
		(*ListaDeIDPedidos) = (*pnodo);
	}	
	else
	{
		(*pnodo)->Ant = *ListaDeIDPedidos_Ult;	
		(*pnodo)->Sgt = NULL;
		(*ListaDeIDPedidos_Ult)->Sgt = (*pnodo);
	}
	
	*ListaDeIDPedidos_Ult=*pnodo;
	
}

void imprimirCola(cliente *ptrActual){

   if(ptrActual==NULL)
      printf("La cola esta vacia\n");

   else{
   
		printf("La Cola es: \n");
		while(ptrActual!=NULL){ 
			printf("%i->",ptrActual->socketCliente);
			/*printf("data %s\n",ptrActual->data);*/
			ptrActual=ptrActual->Sgt;  
		}
		printf("NULL \n");  
   }
   
} 

void imprimirCola2(struct ListaIDdescriptors *ptrActual){

   if(ptrActual==NULL)
      printf("La cola esta vacia\n");

   else{
   
		printf("La Cola es: \n");
		while(ptrActual!=NULL){ 
			/*printf("%s->",ptrActual->sDescriptorID_delPedido);*/
			/*printf("%s->",ptrActual->data);*/
			/*printf("%s->",ptrActual->discoAsignado);*/
			printf("%i->",ptrActual->numeroSector);
			ptrActual=ptrActual->Sgt;  
		}
		printf("NULL \n");  
   }
   
} 






void imprimirCola3(struct ListaIDdescriptors *ptrActual){

   if(ptrActual==NULL)
      printf("La cola esta vacia\n");

   else{
   
		printf("La Cola es: \n");
		while(ptrActual!=NULL){ 
			/*printf("%s->",ptrActual->sDescriptorID_delPedido);
			printf("%s->",ptrActual->data);*/
			printf("%i->",ptrActual->estado);
			ptrActual=ptrActual->Sgt;  
		}
		printf("NULL \n");  
   }
   
} 


void imprimirCola5(t_control *ptrActual){


   if(ptrActual==NULL)
      printf("La cola esta vacia\n");

   else{
   
		printf("La Cola es: \n");
		while(ptrActual!=NULL){ 
			printf("%s->",ptrActual->sDescriptorID_delPedido);
			ptrActual=ptrActual->Sgt;  
		}
		printf("NULL \n");  
   }
} 


struct ListaIDdescriptors * BuscarPorNumeroSector(struct ListaIDdescriptors * ListaDeIDPedidos,int numero)		//busca un la lista de descriptores del disco por opciones: (en este el sDescriptorID_delDA que sea igual sDescriptorID, y lo saca de la lista)

{
	struct ListaIDdescriptors * pNodo;
	pNodo = ListaDeIDPedidos;

	while(pNodo != NULL)
	{
		if(pNodo->numeroSector==numero)
			return pNodo;
		pNodo = pNodo->Sgt;
	}
	printf("NO SE ENCONTRO Nro Sector\n");
	return NULL;

}





int	CambiaPosicionDelNodo(struct DiscoConocido ** pnodoDisco)
{



if((ListaDiscos == NULL) || (ListaDiscos_Ult == NULL))
	return -1;


if((*pnodoDisco) != ListaDiscos_Ult )
	{
	if ((*pnodoDisco)->Ant != NULL)
		{
		(*pnodoDisco)->Ant->Sgt = (*pnodoDisco)->Sgt;
		(*pnodoDisco)->Sgt->Ant = (*pnodoDisco)->Ant;

		}
	else				/* pnodo es el primero de la lista */
		{
		(*pnodoDisco)->Sgt->Ant = NULL;
		ListaDiscos = (*pnodoDisco)->Sgt;
		}

	ListaDiscos_Ult->Sgt = (*pnodoDisco);
	(*pnodoDisco)->Ant = ListaDiscos_Ult;

	ListaDiscos_Ult = (*pnodoDisco);
	ListaDiscos_Ult->Sgt = NULL;

	}

return 0;
}
	
	
pedido * BuscarPedidoEnListaDeDisco_Escr(pedido* ListaDeIDPedidos,pedido* ListaDeIDPedidos_Ult, int owner)
{

	pedido *pNodo = ListaDeIDPedidos;

	while(pNodo != NULL)
	{
		if(pNodo->operacion==1 && pNodo->estado==2 && pNodo->owner == owner){ //Estado == 1; atendido
			break;
		}
		pNodo = pNodo->Sgt;
	}
	
	return pNodo;
	
}


pedido * BuscarPedidoEnListaDeDisco_Lect(pedido* ListaDeIDPedidos,pedido* ListaDeIDPedidos_Ult, int sector, int owner)
{

	pedido *pNodo = ListaDeIDPedidos;

	while(pNodo != NULL)
	{
		if(pNodo->operacion==0 && pNodo->estado==2 && pNodo->owner == owner && pNodo->numeroSector == sector) {//Estado == 1; atendido
			break;
		}
		pNodo = pNodo->Sgt;
	}
	
	return pNodo;
}

pedido * BuscarPendienteDeEnviar(pedido* ListaDeIDPedidos)
{
	
	pedido *pNodo = ListaDeIDPedidos;

	while(pNodo != NULL)
	{
		if(pNodo->estado==0){ //Estado == 1; atendido
			return pNodo;;
		}	
		pNodo = pNodo->Sgt;
	}
	
	return NULL;
}


struct ListaIDdescriptors * BuscarPorDisco(struct ListaIDdescriptors * ListaDeIDPedidos,char* nombreDisco)		//busca un la lista de descriptores del disco por opciones: (en este el sDescriptorID_delDA que sea igual sDescriptorID, y lo saca de la lista)

{
	struct ListaIDdescriptors * pNodo;
	pNodo = ListaDeIDPedidos;

	while(pNodo != NULL)
	{
		if(!(strcmp(pNodo->discoAsignado,nombreDisco)))
			return pNodo;
		pNodo = pNodo->Sgt;
	}
	printf("No se encontro pedido correspondiente a ese disco\n");
	return NULL;

}


pedido * BuscarPedidoEnListaDeDisco_Lect2(pedido* ListaDeIDPedidos,pedido* ListaDeIDPedidos_Ult,int owner)
{

	pedido *pNodo = ListaDeIDPedidos;

	while(pNodo != NULL)
	{
		if(pNodo->operacion==0 && pNodo->estado==2 && pNodo->owner == owner) {//Estado == 1; atendido
			break;
		}
		pNodo = pNodo->Sgt;
	}
	
	return pNodo;
}

pedido * BuscarPedidoEnListaDeDisco_Lect3(pedido* ListaDeIDPedidos,pedido* ListaDeIDPedidos_Ult)
{

	pedido *pNodo = ListaDeIDPedidos;

	while(pNodo != NULL)
	{
		if(pNodo->operacion==0 && pNodo->estado==2) {//Estado == 1; atendido
			break;
		}
		pNodo = pNodo->Sgt;
	}
	
	return pNodo;
}

pedido * BuscarPedidoEnListaDeDisco_Escr2(pedido* ListaDeIDPedidos,pedido* ListaDeIDPedidos_Ult)
{

	pedido *pNodo = ListaDeIDPedidos;

	while(pNodo != NULL)
	{
		if(pNodo->operacion==1 && pNodo->estado==2 ){ //Estado == 1; atendido
			break;
		}
		pNodo = pNodo->Sgt;
	}
	
	return pNodo;
	
}



struct DiscoConocido * BuscarDiscoSinc()	
{

struct DiscoConocido * pNodo;
	
	
	pNodo = ListaDiscos;

	while(pNodo != NULL)
		{
		if(pNodo->Estado == SINCRONIZANDO)
			return pNodo;
		pNodo = pNodo->Sgt;
		}

return NULL;

}